package handler

import (
    "fcs-api/src/app/business"
    "fcs-api/src/app/model"
    "net/http"
    "strconv"

    i18n "git.inspur.com/x/common/i18n"
    "github.com/emicklei/go-restful"
)

func (api *APIHandler) handleCreateDomain(request *restful.Request, response *restful.Response) {
    logger.Debug("handleCreateDomain start.")

    fcClient, err := GetFcClient(api)
    if err != nil {
        _ = logger.Error("handleCreateDomain get cmanagerconfig error %v", err)
        handleInternalError(response, model.InternalServerError(model.DomainError, i18n.GetMessage(request.Request, "fcs.domain.create")))
        return
    }
    domainInfo, err := ReadAndValidateDomain(request)
    if err != nil {
        _ = logger.Error("handleCreateDomain ReadAndValidateDomain error %v", err)
        handleInternalError(response, model.InternalServerError(model.DomainError, i18n.GetMessage(request.Request, "fcs.domain.create_param")))
        return
    }
    logger.Debug("handleCreateDomain domainInfo : %v", domainInfo)
    has, err := model.CheckDomainExist(domainInfo.A5tId, domainInfo.DomainName)
    if err != nil {
        _ = logger.Error("handleCreateDomain CheckDomainExist error %v", err)
        handleInternalError(response, model.InternalServerError(model.DomainError, i18n.GetMessage(request.Request, "fcs.domain.create")))
        return
    }
    if has {
        handleInternalError(response, model.InternalServerError(model.DomainError, i18n.GetMessage(request.Request, "fcs.domain.create_dup")))
        return
    }

    // TODO: 校验域名的备案状态
    // TODO: 校验域名的 CNAME 解析状态

    // 创建 Ingress
    err = business.CreateDomainIngress(fcClient, domainInfo)
    if err != nil {
        _ = logger.Error("handleCreateDomain CreateDomainIngress error %v", err)
        handleInternalError(response, model.InternalServerError(model.DomainError, i18n.GetMessage(request.Request, "fcs.domain.create")))
        return
    }

    //更新数据库
    domainInfo, err = model.CreateDomain(domainInfo)
    if err != nil {
        handleInternalError(response, model.InternalServerError(model.DomainError, i18n.GetMessage(request.Request, "fcs.domain.create")))
        return
    }

    _ = response.WriteHeaderAndEntity(http.StatusOK, domainInfo)
}

func (api *APIHandler) handleUpdateDomain(request *restful.Request, response *restful.Response) {
    logger.Debug("handleUpdateDomain start.")

    fcClient, err := GetFcClient(api)
    if err != nil {
        _ = logger.Error("handleUpdateDomain get cmanagerconfig error %v", err)
        handleInternalError(response, model.InternalServerError(model.DomainError, i18n.GetMessage(request.Request, "fcs.domain.update")))
        return
    }
    domainInfo, err := ReadAndValidateDomain(request)
    if err != nil {
        _ = logger.Error("handleUpdateDomain ReadAndValidateDomain error %v", err)
        handleInternalError(response, model.InternalServerError(model.DomainError, i18n.GetMessage(request.Request, "fcs.domain.update_param")))
        return
    }
    domainInfo.Id = request.PathParameter("domainId")
    // 如果自定义域名有对应的证书，则把 domainInfo.Cert.Id 填充为已有的
    user := currentUser(request)
    c, err := model.GetCertByDomainId(domainInfo.Id, user)
    if err != nil {
        _ = logger.Error("handleUpdateDomain GetCertByDomainId error %v", err)
        handleInternalError(response, model.InternalServerError(model.DomainError, i18n.GetMessage(request.Request, "fcs.domain.update")))
        return
    }
    if c != nil {
        if domainInfo.Cert == nil {
            domainInfo.Cert = &model.Cert{
                Id: c.Id,
            }
        } else {
            domainInfo.Cert.Id = c.Id
        }
    }
    logger.Debug("handleUpdateDomain domainInfo : %v", domainInfo)

    // 先获取数据库内已有的数据
    oldDomainInfo, err := model.GetDomainById(domainInfo.Id, user)
    if err != nil {
        handleInternalError(response, model.InternalServerError(model.DomainError, i18n.GetMessage(request.Request, "fcs.domain.update")))
        return
    }
    // 自定义域名名称不能修改
    if oldDomainInfo.DomainName != domainInfo.DomainName {
        handleInternalError(response, model.InternalServerError(model.DomainError, i18n.GetMessage(request.Request, "fcs.domain.update_name")))
        return
    }
    // 可以修改支持协议
    // 可以修改证书
    // 可以修改路由规则
    err = business.CreateDomainIngress(fcClient, domainInfo)
    if err != nil {
        _ = logger.Error("handleUpdateDomain CreateDomainIngress error %v", err)
        handleInternalError(response, model.InternalServerError(model.DomainError, i18n.GetMessage(request.Request, "fcs.domain.update")))
        return
    }

    domainInfo, err = model.UpdateDomain(domainInfo, user)
    if err != nil {
        handleInternalError(response, model.InternalServerError(model.DomainError, i18n.GetMessage(request.Request, "fcs.domain.update")))
        return
    }
    _ = response.WriteHeaderAndEntity(http.StatusOK, domainInfo)
}

func (api *APIHandler) handleDeleteDomain(request *restful.Request, response *restful.Response) {
    logger.Debug("handleDeleteDomain start.")

    fcClient, err := GetFcClient(api)
    if err != nil {
        _ = logger.Error("handleDeleteDomain get cmanagerconfig error %v", err)
        handleInternalError(response, model.InternalServerError(model.DomainError, i18n.GetMessage(request.Request, "fcs.domain.delete")))
        return
    }
    domainId := request.PathParameter("domainId")
    user := currentUser(request)
    domainInfo, err := model.GetDomainById(domainId, user)
    if err != nil {
        handleInternalError(response, model.InternalServerError(model.DomainError, i18n.GetMessage(request.Request, "fcs.domain.delete")))
        return
    }

    err = business.DeleteDomainIngress(fcClient, domainInfo)
    if err != nil {
        _ = logger.Error("handleDeleteDomain DeleteDomainIngress error %v", err)
        handleInternalError(response, model.InternalServerError(model.DomainError, i18n.GetMessage(request.Request, "fcs.domain.delete")))
        return
    }

    if err := model.DeleteDomain(domainInfo.Id, user); err != nil {
        handleInternalError(response, model.InternalServerError(model.DomainError, i18n.GetMessage(request.Request, "fcs.domain.delete")))
        return
    }
}

func (api *APIHandler) handleGetDomainList(request *restful.Request, response *restful.Response) {
    logger.Debug("handleGetDomainList start.")
    pageNoStr := request.QueryParameter("pageNo")
    pageSizeStr := request.QueryParameter("pageSize")

    var err error
    pageNo, pageSize := 1, 1000000
    if pageNoStr != "" || pageSizeStr != "" {
        pageNo, err = strconv.Atoi(pageNoStr)
        if err != nil {
            handleInternalError(response, model.InternalServerError(model.DomainError, i18n.GetMessage(request.Request, "fcs.domain.query_param")))
            return
        }
        pageSize, err = strconv.Atoi(pageSizeStr)
        if err != nil {
            handleInternalError(response, model.InternalServerError(model.DomainError, i18n.GetMessage(request.Request, "fcs.domain.query_param")))
            return
        }
    }

    user := currentUser(request)
    domainPage, err := model.GetDomainList(user, pageNo, pageSize)
    if err != nil {
        handleInternalError(response, model.InternalServerError(model.DomainError, i18n.GetMessage(request.Request, "fcs.domain.query")))
        return
    }
    _ = response.WriteHeaderAndEntity(http.StatusOK, domainPage)
}

func (api *APIHandler) handleGetDomainDetail(request *restful.Request, response *restful.Response) {
    logger.Debug("handleGetDomainDetail start.")
    domainId := request.PathParameter("domainId")
    user := currentUser(request)
    domainInfo, err := model.GetDomainById(domainId, user)
    if err != nil {
        handleInternalError(response, model.InternalServerError(model.DomainError, i18n.GetMessage(request.Request, "fcs.domain.detail")))
        return
    }
    if domainInfo.Id == "" {
        handleInternalError(response, model.InternalServerError(model.DomainError, i18n.GetMessage(request.Request, "fcs.domain.detail")))
        return
    }
    _ = response.WriteHeaderAndEntity(http.StatusOK, domainInfo)
}

func (api *APIHandler) handleCheckDomainExist(request *restful.Request, response *restful.Response) {
    domainName := request.QueryParameter("domainName")
    user := currentUser(request)
    exist, err := model.CheckDomainExist(user.Id, domainName)
    if err != nil {
        _ = logger.Error("handleCheckDomainExist CheckDomainExist error %v", err)
    }
    _ = response.WriteHeaderAndEntity(http.StatusOK, map[string]interface{}{"exist": exist})
}
